<?php
/**
 * Description of CYui
 *
 * @author Sergei
 */
class CYui
{
    const DEFAULT_DATE_FORMAT = "%d.%m.%Y";
    const DB_DATE_FORMAT = "%Y-%m-%d";
    private static $yuiLocalUrl;
    private static $yuiYahooUrl = 'http://yui.yahooapis.com/2.7.0/';
    private static $ajaxTimeout;
    private static $highlighter;

    public static function init($useLocalHosting = true, $useCodeHighlight = false, $ajaxTimeoutPeriod = 5000) {
        self::$yuiLocalUrl = Yii::app()->getAssetManager()->publish(dirname(__FILE__).DIRECTORY_SEPARATOR.'yui').'/';
        if($useLocalHosting)  self::$yuiYahooUrl = self::$yuiLocalUrl;
        self::$ajaxTimeout = $ajaxTimeoutPeriod;
        self::registerYuiScript(array('build/yuiloader/yuiloader-min.js'));
        self::registerCustomScript(array('initYUI.js'));
        if($useCodeHighlight)
        {
            self::registerCustomCss(array('YuiAdd/highlight.css'));
            require_once('TParser.php');
            self::$highlighter = new TParser();
        }
        return '<script>YAHOO.YuiWidget.init({ YuiPath: "'.self::$yuiYahooUrl.'build/", LocalPath: "'.self::$yuiLocalUrl.'", AjaxTimeout: '.self::$ajaxTimeout.' });</script>';
    }

    /**************    Internal class function   *****************************/
    protected static function registerYuiScript($names) {
        $clientScript = Yii::app()->getClientScript();
        foreach($names as $name) {
            if(!$clientScript->isScriptFileRegistered(self::$yuiYahooUrl.$name))
            $clientScript->registerScriptFile(self::$yuiYahooUrl.$name);
        }
    }
    protected static function registerCustomScript($names) {
        $clientScript = Yii::app()->getClientScript();
        foreach($names as $name) {
            if(!$clientScript->isScriptFileRegistered(self::$yuiLocalUrl.$name))
            $clientScript->registerScriptFile(self::$yuiLocalUrl.$name);
        }
    }
    protected static function registerYuiCss($names) {
        $clientScript = Yii::app()->getClientScript();
        foreach($names as $name) {
            if(!$clientScript->isCssFileRegistered(self::$yuiYahooUrl.$name))
            $clientScript->registerCssFile(self::$yuiYahooUrl.$name);
        }
    }
    protected static function registerCustomCss($names) {
        $clientScript = Yii::app()->getClientScript();
        foreach($names as $name) {
            if(!$clientScript->isCssFileRegistered(self::$yuiLocalUrl.$name))
            $clientScript->registerCssFile(self::$yuiLocalUrl.$name);
        }
    }

    protected static function resolveName($model,&$attribute) {
        if(($pos=strpos($attribute,'['))!==false) {
            $sub=substr($attribute,$pos);
            $attribute=substr($attribute,0,$pos);
            return get_class($model).$sub.'['.$attribute.']';
        }
        else
        return get_class($model).'['.$attribute.']';
    }
    protected static function getIdByName($name) {
        return str_replace(array('[]', '][', '[', ']'), array('', '_', '_', ''), $name);
    }

    public static function codeHighlight($str, $language) {
        if(isset(self::$highlighter))
        return self::$highlighter->parseBlock($str, $language);
        else
        return $str;
    }
    public static function buildAjaxOptions($responseUrl, $reciverId)
    {
        return array('responseUrl'=>$responseUrl, 'reciver'=>$reciverId);
    }
    public static function getLocalUrl() { return self::$yuiLocalUrl; }
    public static function getYahooUrl() { return self::$yuiYahooUrl; }
    public static function getDefaultDateFormat() { return self::DEFAULT_DATE_FORMAT ; }
    public static function getDbDateFormat() { return self::DB_DATE_FORMAT; }
    public static function getLocalize($el)
    {
        require_once "CYuiLocalize.php";
        if(array_key_exists(Yii::app()->language, CYuiLOcalize::$localizeYUI)=== true)
            return CYuiLOcalize::$localizeYUI[Yii::app()->language][$el];
        else
            return ($el === 'calendar')? null : CYuiLOcalize::$localizeYUI['en'][$el];
    }
    /**************    CALENDAR WIDGETS   ************************/
    public static function buildCalendarOptions($monthsVisible = 1, $title = null)
    {
        $localize = self::getLocalize('calendar');
        $calOptions = array(
            'close'=>false,
            'LOCALE_WEEKDAYS'=>'short',
            'LOCALE_MONTHS'=>'long',
            'PAGES'=>$monthsVisible,
        );
        if(isset($title)) $calOptions['title'] = $title;
        if(isset($localize))
        {
            $calOptions['START_WEEKDAY']= $localize['weekStart'];
            $calOptions['MONTHS_LONG']= $localize['months'];
            $calOptions['WEEKDAYS_SHORT']= $localize['days'];
        }
        return $calOptions;
    }
    private static function wCalendar($activeMode, $name, $id, $label, $value, $formatStr, $monthsVisible, $ajax, $openOnClick, $sendId, $recvId, $recvAttribute = 'value') {
        $style = ($openOnClick)? ' style="position:absolute; z-index:3;"' : '' ;
        $calOptions = array(
            'name'=>$id,
            'initOption'=>self::buildCalendarOptions($monthsVisible, $label),
            'openOnClick'=>$openOnClick,
            'activeMode'=>$activeMode,
            'reciver'=>$recvId,
            'reciverAttribute'=>$recvAttribute,
            'sender'=>$sendId,
            'format'=>$formatStr,
            'dbFormat'=>self::DB_DATE_FORMAT,
        );
        if(isset($ajax)) $calOptions['ajax'] = $ajax;
        $calOptions['pagedate'] = date('m/Y', strtotime($value));
        $calOptions['selected'] = date('m/d/Y', strtotime($value));
        $outStr = '
        <div id="'.$id.'Container"'.$style.'></div>
        <script type="text/javascript">
            var par'.$id.' = '.json_encode($calOptions).'
            YAHOO.util.Get.script("'.self::$yuiLocalUrl.'wCalendar.js", {
                                       onSuccess: function() {
                                                    var cal'.$id.' = new YAHOO.YuiWidget.calendar;
                                                    cal'.$id.'.init(par'.$id.') } })
         </script>
        ';
        return $outStr;
    }
    public static function calendar($name, $value = null, $label = null, $formatStr = self::DEFAULT_DATE_FORMAT, $monthsVisible = 1, $ajax = null) {
        if(!isset($value)) $value = strftime($formatStr);
        if(!isset($label)) $label = "";
        return
        '<input type="hidden" id="'.$name.'" name="'.$name.'" value="'.$value.'" />
        '.self::wCalendar(false, $name, $name, $label, $value, $formatStr, $monthsVisible, $ajax, false, $name, $name);
    }
    public static function inputCalendar($name, $value = null, $label = null, $formatStr = self::DEFAULT_DATE_FORMAT, $monthsVisible = 1, $ajax = null) {
        if(!isset($value)) $value = strftime($formatStr);
        if(!isset($label)) $label = $name;
        return
         '<input type="input" id="'.$name.'" name="'.$name.'" value="'.$value.'" />
        '.self::wCalendar(false, $name, $name, $label, $value, $formatStr, $monthsVisible, $ajax, true, $name, $name);
    }
    public static function buttonCalendar($name, $value = null, $formatStr = self::DEFAULT_DATE_FORMAT, $monthsVisible = 1, $ajax = null) {
        if(!isset($value)) $value = strftime($formatStr);
        return
        '<input type="button" id="'.$name.'btn" name="'.$name.'btn" value="'.$value.'" />
         <input type="hidden" id="'.$name.'" name="'.$name.'" value="'.$value.'" />
        '.self::wCalendar(false, $name, $name, null, $value, $formatStr, $monthsVisible, $ajax, true, $name.'btn', $name);
    }
    public static function activeCalendar($model, $attribute, $formatStr = self::DEFAULT_DATE_FORMAT, $monthsVisible = 1, $ajax = null) {
        $name = self::resolveName($model, $attribute);
        $id = self::getIdByName($name);
        $label = $model->getAttributeLabel($attribute);
        $value = strftime($formatStr, strtotime($model->$attribute));
        return
        '<input type="hidden" id="'.$name.'" name="'.$name.'" value="'.$value.'" />
        '.self::wCalendar(true, $name, $id, $label, $value, $formatStr, $monthsVisible, $ajax, false, $name, $name);
    }
    public static function activeInputCalendar($model, $attribute, $formatStr = self::DEFAULT_DATE_FORMAT, $monthsVisible = 1, $ajax = null) {
        $name = self::resolveName($model, $attribute);
        $id = self::getIdByName($name);
        $label = $model->getAttributeLabel($attribute);
        $value = strftime($formatStr, strtotime($model->$attribute));
        $valueDB = strftime(self::DB_DATE_FORMAT, strtotime($model->$attribute));
        return
         '<input type="input" id="'.$name.'inp" name="'.$name.'" value="'.$value.'" />
         <input type="hidden" id="'.$name.'" name="'.$name.'" value="'.$valueDB.'" />
        '.self::wCalendar(true, $name, $id, null, $value, $formatStr, $monthsVisible, $ajax, true, $name.'inp', $name);
    }
    public static function activeButtonCalendar($model, $attribute, $formatStr = self::DEFAULT_DATE_FORMAT, $monthsVisible = 1, $ajax = null) {
        $name = self::resolveName($model, $attribute);
        $id = self::getIdByName($name);
        $label = $model->getAttributeLabel($attribute);
        $value = strftime($formatStr, strtotime($model->$attribute));
        $valueDB = strftime(self::DB_DATE_FORMAT, strtotime($model->$attribute));
        return
        '<input type="button" id="'.$name.'btn" name="'.$name.'btn" value="'.$value.'" />
         <input type="hidden" id="'.$name.'" name="'.$name.'" value="'.$valueDB.'" />
        '.self::wCalendar(true, $name, $id, null, $value, $formatStr, $monthsVisible, $ajax, true, $name.'btn', $name);
    }

    /******************* TREE VIEW WIDGETS **************************/
    private static function _localizeTree() {
        $arr = self::getLocalize('tree');
        return array(
            'ADD_NODE'=>$arr['addTreeNode'],
            'DELETE_NODE'=>$arr['deleteTreeNode'],
            'CONFIRM_DELETE'=>$arr['confirmDeleteNode'],
            'EDIT_NODE'=>$arr['editTreeNode'],
            'CUT_NODE'=>$arr['cutTreeNode'],
            'PASTE_NODE'=>$arr['pasteTreeNode']
        );
    }
    private static function wTree($name, $id, $value, $tableTree, $editable, $asyncMode, $visualStyle, $ajax) {
        switch($visualStyle)
        {
            case 'folder':
                $css ='YAHOO.util.Get.css("'.self::$yuiLocalUrl.'YuiAdd/treeview/css/folders/tree.css");';
                break;
            case 'menu'  :
                $css ='YAHOO.util.Get.css("'.self::$yuiLocalUrl.'YuiAdd/treeview/css/menu/tree.css");';
                break;
            default:
                $css = '';
            }
            $options = array(
            'id'=>$id,
            'value'=>$value,
            'editable'=>(int)$editable,
            'asyncMode'=>(int)$asyncMode,
            'tableName'=>$tableTree
            );
            if(isset($ajax)) $options['ajax'] = $ajax;
            if($editable) $options['localize'] = self::_localizeTree();
            return '
        <div id="'.$id.'Tree" class="'.$visualStyle.'"></div>
        <input type="hidden" id="'.$id.'" name="'.$name.'" value="'.$value.'" />
        <script type="text/javascript">
            var par'.$id.' = '.json_encode($options).';
            '.$css.'
            YAHOO.util.Get.script("'.self::$yuiLocalUrl.'wTreeData.js", {
                                       onSuccess: function() {
                                                    var tree'.$id.' = new YAHOO.YuiWidget.treeData;
                                                    tree'.$id.'.init(par'.$id.') } })
         </script>';
    }
    public static function tree($name, $value, $tableTree, $editable=false, $asyncMode=true, $visualStyle='default', $ajax = null) {
            if( (!isset($value)) or ($value < 1) ) $value = 1;
            return self::wTree($name, $name, $value, $tableTree, $editable, $asyncMode, $visualStyle, $ajax);
        }
    public static function activeTree($model, $attribute,  $tableTree, $editable=false, $asyncMode=true, $visualStyle='default', $ajax = null) {
            $name = self::resolveName($model, $attribute);
            $id = self::getIdByName($name);
            $value = ($model->$attribute < 1) ? 1 : $model->$attribute;
            return self::wTree($name, $id, $value, $tableTree, $editable, $asyncMode, $visualStyle, $ajax);
        }

    /*******************  TAB VIEW WIDGET ***************************/
    // create one tab from passed content
    public static function tabviewContentTab($content, $label, $disabled = false)
    {
        $tab = array('content'=>$content, 'label'=>$label);
        if($disabled) $tab['disabled'] = $disabled;
        return $tab;
    }
    // create one tab to redirect to another page
    public static function tabviewRedirectTab($url, $label, $disabled = false)
    {
        $tab = array('content'=>'link '.$url, 'label'=>$label);
        if($disabled) $tab['disabled'] = $disabled;
        return $tab;
    }
    // create one tab from DIV content
    public static function tabviewDivTab($div, $label, $disabled = false)
    {
        $tab = array('contentEl'=>$div, 'label'=>$label);
        if($disabled) $tab['disabled'] = $disabled;
        return $tab;
    }
    // create one tab is loaded dynamically from this url when tab is activated
    public static function tabviewAjaxTab($url, $label, $cacheData = true, $dataTimeout = null, $loadMethod = 'GET', $disabled = false)
    {
        $tab = array('label'=>$label, 'dataSrc'=>$url,
                     'cacheData'=>$cacheData, 'loadMethod'=>$loadMethod);
        if($disabled) $tab['disabled'] = $disabled;
        if($dataTimeout) $tab['dataTimeout'] = $dataTimeout;
        return $tab;
    }
    public static function tabview($id, $tabs, $activeTab = 0, $orientation = 'top', $ajax = null){
            $options = array(
             'id'=>$id,
             'activeTab'=>$activeTab,
             'orientation'=>$orientation,
             'tabs'=>$tabs
            );
            if(isset($ajax)) $options['ajax'] = $ajax;
            return '
        <div id="'.$id.'Div"></div>
        <input type="hidden" id="'.$id.'" name="'.$id.'"  value="'.$activeTab.'" />
        <script type="text/javascript">
            var par'.$id.' = '.json_encode($options).' ;
            YAHOO.util.Get.script(["'.self::$yuiYahooUrl.'build/utilities/utilities.js",
                                    "'.self::$yuiLocalUrl.'dispatcher-min.js",
                                    "'.self::$yuiLocalUrl.'wTabView.js"], {
                                       onSuccess: function() {
                                                    var tab'.$id.' = new YAHOO.YuiWidget.tabView;
                                                    tab'.$id.'.init(par'.$id.') } })
         </script>
        ';
        }

    /******************  AUTOCOMLETE  *************************************/
    public static function autocomplete($id, $responseUrl, $value = null, $responseFieldName='name', $ajax = null, $options=null) {
            $options = array(
            'id'=>$id,
            'responseUrl'=>$responseUrl,
            'responseFieldName'=>$responseFieldName,
            'options'=>$options,
            );
            if(isset($ajax)) $options['ajax'] = $ajax;
            return '
                <div id="ac'.$id.'">
                    <input id="'.$id.'" name="'.$id.'" type="text" value="'.$value.'">
                    <div id="acContainer'.$id.'"></div>
                </div>
                <script type="text/javascript">
                    var par'.$id.' = '.json_encode($options).';
                    YAHOO.util.Get.script("'.self::$yuiLocalUrl.'wAutocomplete.js", {
                                       onSuccess: function() {
                                                    var ac'.$id.' = new YAHOO.YuiWidget.autocomplete;
                                                    ac'.$id.'.init(par'.$id.');
                                                    } })
                </script>
               ';
        }
    public static function activeAutocomplete($model, $attribute, $responseUrl, $responseFieldName=null, $ajax = null, $options=null) {
            $name = self::resolveName($model, $attribute);
            $id = self::getIdByName($name);
            return self::autocomplete($id, $responseUrl, $model->$attribute, $responseFieldName, $ajax, $options);
        }
    public static function autocompleteTable($id, $value, $tableName, $fieldName, $ajax = null, $options=null) {
            $responseUrl = '/yui/autocomplete/table/'.$tableName.'/field/'.$fieldName.'/query/';
            return self::autocomplete($id, $responseUrl, $value, $fieldName, $ajax, $options);
        }
    public static function activeAutocompleteTable($model, $attribute,  $tableName, $fieldName, $ajax = null, $options=null) {
            $name = self::resolveName($model, $attribute);
            $id = self::getIdByName($name);
            $responseUrl = '/yui/autocomplete/table/'.$tableName.'/field/'.$fieldName.'/query/';
            return self::autocomplete($id, $responseUrl, $model->$attribute, $fieldName, $ajax, $options);
        }

    /**********************  Rich Text Editor  ******************************/
    private static function wEditor($opt, $data)
    {
        // Attempt to filter out MS Word HTML from the Editor's output
        $opt['cfg']['filterWord '] = true;
        //place the new content back into the text area before the form is submitted
        $opt['cfg']['handleSubmit'] = !isset($opt['ajaxSaveUrl']);
        $opt['cfg']['resize'] = true;
        // build html-fragment to output
        if(!isset($data)) $data = '';
        $outStr = '<textarea id="'.$opt['id'].'" name="'.$opt['id'].'" rows="20" cols="70">'.$data.'</textarea>
                <script type="text/javascript">
                    YAHOO.util.Get.script("'.self::$yuiLocalUrl.'wEditor.js", {
                                       onSuccess: function() {
                                                    var editor'.$opt['id'].' = new YAHOO.YuiWidget.editor;
                                                    editor'.$opt['id'].'.init('.json_encode($opt).');
                                                    } })
                </script>';
        return $outStr;
    }
    public static function editor($id, $data = null, $ajaxSaveUrl = null, $height = '250px', $width = '500px', $autoHeight = false, $animate = true)
    {
        $options = array(
            'id'=>$id,
            'cfg'=>array('height'=>$height,
                         'width'=>$width,
                         'animate'=>$animate,
                         'autoHeight'=>$autoHeight,
                        ),
            'type'=>'editor',
        );
        if(isset($ajaxSaveUrl)) $options['ajaxSaveUrl'] = $ajaxSaveUrl;
        return self::wEditor($options, $data);
    }
    public static function simpleEditor($id, $data = null, $ajaxSaveUrl = null, $height = '250px', $width = '500px', $autoHeight = false)
    {
        $options = array(
            'id'=>$id,
            'cfg'=>array('height'=>$height,
                         'width'=>$width,
                         'autoHeight'=>$autoHeight,
                        ),
            'type'=>'simpleeditor',
        );
        if(isset($ajaxSaveUrl)) $options['ajaxSaveUrl'] = $ajaxSaveUrl;
        return self::wEditor($options, $data);
    }

    /*************************  LightBox  ***********************************/
    public static function buildImagesListFromPath($imagesPath)
    {
        $fileArray = array();
        $counter = 0;
        if(!isset($imagesPath)) throw new CHttpException(500,'Path to images must be set!');
        if ($handle = opendir($imagesPath))
        {
            while (false !== ($file = readdir($handle)))
            {
                if ($file[0] != ".")
                {
                    $counter++;
                    $fileArray['image'.$counter] = array('url'=>'/'.$imagesPath.'/'.$file);
                }
            }
            closedir($handle);
        }
        return $fileArray;
    }
    public static function lightboxGallery($id, $images, $ctrlVisible = true, $tooltipVisible = false, $modal = true, $hasThumbnails = true)
    {
        $opt['options'] = array('id'=>$id);
        if(!$hasThumbnails) $opt['options']['hasThumbnails'] = $hasThumbnails;
        if(!$ctrlVisible) $opt['options']['ctrlVisible'] = $ctrlVisible;
        if(!$tooltipVisible) $opt['options']['tooltipVisible'] = $tooltipVisible;
        if(!$modal) $opt['options']['modal'] = $modal;
        $opt['images'] = $images;
        $outStr = '<script type="text/javascript">
                    YAHOO.util.Get.css("'.self::$yuiLocalUrl.'YuiAdd/lightbox/lightbox.css");
                    YAHOO.util.Get.script( ["'.self::$yuiYahooUrl.'build/utilities/utilities.js",
                                            "'.self::$yuiLocalUrl.'YuiAdd/lightbox/Lightbox-min.js",
                                            "'.self::$yuiLocalUrl.'wLightbox.js"], {
                                       onSuccess: function() {
                                                    var lb'.$id.' = new YAHOO.YuiWidget.lightbox;
                                                    lb'.$id.'.init('.json_encode($opt).');
                                                    } })
                </script>';
        return $outStr;
    }
    public static function lightboxAttachTo($htmlId,  $images, $ctrlVisible = false, $tooltipVisible = false, $modal = true)
    {
        if(!$ctrlVisible) $opt['options']['ctrlVisible'] = $ctrlVisible;
        if(!$tooltipVisible) $opt['options']['tooltipVisible'] = $tooltipVisible;
        if(!$modal) $opt['options']['modal'] = $modal;
        $opt['attachEl'] = $htmlId;
        $opt['images'] = $images;
        $outStr = '<script type="text/javascript">
                    YAHOO.util.Get.css("'.self::$yuiLocalUrl.'YuiAdd/lightbox/lightbox.css");
                    YAHOO.util.Get.script( ["'.self::$yuiYahooUrl.'build/utilities/utilities.js",
                                            "'.self::$yuiLocalUrl.'YuiAdd/lightbox/Lightbox-min.js",
                                            "'.self::$yuiLocalUrl.'wLightbox.js"], {
                                       onSuccess: function() {
                                                    var lb'.$htmlId.' = new YAHOO.YuiWidget.lightbox;
                                                    lb'.$htmlId.'.init('.json_encode($opt).');
                                                    } })
                </script>';
        return $outStr;
    }

    /*************************  Layout  ************************************/
    public static function layoutUnitCenter($bodyDIV, $header = null, $footer = null, $gutter = '2px', $scroll = true)
    {
        $options = array('position'=>'center', 'body'=>$bodyDIV, 'gutter'=>$gutter, 'scroll'=>$scroll);
        if(isset($header)) $options['header'] = $header;
        if(isset($footer)) $options['footer'] = $footer;
        return $options;
    }
    public static function layoutUnitLeftRight($position, $bodyDIV, $width, $resize = true, $gutter = '2px',
                                               $header = null, $footer = null, $collapse = true,
                                               $scroll = true, $animate = true)
    {
        $options = array('position'=>$position, 'body'=>$bodyDIV, 'width'=>$width, 'gutter'=>$gutter);
        if(isset($header)) $options['header'] = $header;
        if(isset($footer)) $options['footer'] = $footer;
        if(isset($resize)) $options['resize'] = $resize;
        if(isset($collapse)) $options['collapse'] = $collapse;
        if(isset($scroll)) $options['scroll'] = $scroll;
        if(isset($animate)) $options['animate'] = $animate;
        return $options;

    }
    public static function layoutUnitTopBottom($position, $bodyDIV, $height, $resize = true, $gutter = '2px',
                                               $header = null, $footer = null, $collapse = true, $scroll = true,
                                               $animate = true)
    {
        $options = array('position'=>$position, 'body'=>$bodyDIV, 'height'=>$height, 'gutter'=>$gutter);
        if(isset($header)) $options['header'] = $header;
        if(isset($footer)) $options['footer'] = $footer;
        if(isset($resize)) $options['resize'] = $resize;
        if(isset($collapse)) $options['collapse'] = $collapse;
        if(isset($scroll)) $options['scroll'] = $scroll;
        if(isset($animate)) $options['animate'] = $animate;
        return $options;
    }

    public static function layout($units, $bodyDIV = null)
    {
        $opt['units'] = $units;
        if(isset($bodyDIV)) $opt['area'] = $bodyDIV;
        $outStr = '<script type="text/javascript">
                    YAHOO.util.Get.script("'.self::$yuiLocalUrl.'wLayout.js", {
                                       onSuccess: function() {
                                                    var layout'.$bodyDIV.' = new YAHOO.YuiWidget.layout;
                                                    layout'.$bodyDIV.'.init('.json_encode($opt).');
                                                    } })
                </script>';
        return $outStr;
    }
}
 ?>